/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package org.maze.behaviours;

import java.util.ArrayList;
import org.maze.Maze;
import org.maze.individual.Individual;

/**
 *
 * @author Thomas
 */
public class SimpleFitnessBehaviour extends AbstractFitnessBehaviour implements IFitnessBehaviour{

    public double computeFitness(Individual individual) {
        this.setA(individual.getConfiguration().getAlpha());
        double factorA=0;
        double factorB=0;
        Maze maze = Maze.getInstance();
        ArrayList<Integer> path =individual.getPath();
        if(path.size() <= 0)
            return 0;
        int pos = path.get(path.size()-1);
        int x = pos%maze.getSize();
        int y=pos/maze.getSize();

        double distance_x = (double)maze.getSize() - (double)x;
        double distance_y = (double)maze.getSize() - (double)y;
        double distance = Math.sqrt(distance_x*distance_x + distance_y*distance_y);
        factorA = 1 - (distance/Math.sqrt((double)maze.getSize()*(double)maze.getSize()*2));

        if(!path.isEmpty()){            
            factorB = computeFactorB(path.size(), maze.getSize());
         }else{
            factorB = 0;
         }
        return a* factorA + (1-a) * factorB;
    }

    public double computeFactorB(double pathSize, double mazeSize){
        double factorB = 0;
        double optiPathSize = 2*mazeSize-1;
        double diff = optiPathSize - pathSize;

        double square = Math.pow(diff, 2);
        double max = Math.pow(optiPathSize, 2);
        factorB = (max-square)/max;
        return factorB;
    }
}
